package com.swak.reactivex.transport;

import com.swak.Constants;
import com.swak.exception.RemotingException;
import com.swak.reactivex.transport.quic.QuicNettyClient;
import com.swak.reactivex.transport.quic.QuicNettyServer;
import com.swak.reactivex.transport.resources.LoopResources;
import com.swak.reactivex.transport.udp.UdpNettyPeer;
import com.swak.registry.URL;

/**
 * 数据交换服务器和客户端
 * 
 * @author 618lf
 */
public class Exchangers {

	// ************ UDP Peer 模式 *******************

	public static ExchangePeer peer(URL url, LoopResources resources, ExchangeHandler handler)
			throws RemotingException {
		return new HeaderExchangePeer(new UdpNettyPeer(url, resources, new HeaderExchangeHandler(handler)));
	}

	// ************ CS 模式（UDP、TCP、 QUIC） *******************

	public static ExchangeServer bind(URL url, LoopResources resources, ExchangeHandler handler)
			throws RemotingException {
		return new HeaderExchangeServer(
				doBind(url, resources, new HeartbeatHandler(new HeaderExchangeHandler(handler))));
	}

	private static Server doBind(URL url, LoopResources resources, HeartbeatHandler handler) throws RemotingException {
		if (useQuic(url)) {
			return new QuicNettyServer(url, resources, handler);
		}
		return new NettyServer(url, resources, handler);
	}

	public static ExchangeClient connect(URL url, LoopResources resources, ExchangeHandler handler)
			throws RemotingException {
		return new HeaderExchangeClient(
				doConnect(url, resources, new HeartbeatHandler(new HeaderExchangeHandler(handler))));
	}

	private static Client doConnect(URL url, LoopResources resources, HeartbeatHandler handler)
			throws RemotingException {
		if (useQuic(url)) {
			return new QuicNettyClient(url, resources, handler);
		}
		return new NettyClient(url, resources, handler);
	}

	private static boolean useQuic(URL url) {
		return url.getParameter(Constants.Use_Quic, false) && org.springframework.util.ClassUtils
				.isPresent("io.netty.incubator.codec.quic.QuicChannel", Exchangers.class.getClassLoader());
	}
}
